package edu.usm.roberge.server.weather;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.usm.roberge.server.HtmlChangedException;
import edu.usm.roberge.server.HttpRequest;
import edu.usm.roberge.shared.WeatherForecast;

/**
 * Request to the weather.gov website to retrieve weather results
 * This is a relatively simple exercise as they return the results based
 * on the submitted parameters
 */
public class WeatherRequest {
	private final static String URL = "http://forecast.weather.gov/zipcity.php";
	
	private final HttpRequest req; 
	private final static String INPUT_PARAM = "inputstring";
	
	private final static String GO_PARAM= "Go2";
	private final static String GO_PARAM_VALUE = "Go";

	private final static Pattern TABLE_REG_EX = Pattern.compile("<table(.*?)</table>");
	private final static Pattern CELL_REG_EX = Pattern.compile("<td[^>]*>(.*?)</td>");
	private final static Pattern WEATHER_REG_EX = Pattern.compile("([\\w\\s]*)<img[^>]*>([\\w\\s]*)<font[^>]*>([\\d]*)");
	
	public WeatherRequest() {
		req = new HttpRequest(URL);
	}
	
	public List<WeatherForecast> getResultPage(String city, String state) throws HtmlChangedException {
		String inputParamValue = city + "," + state;
		String resp = req.setPostRequest()
		   .addParameter(INPUT_PARAM, inputParamValue)
		   .addParameter(GO_PARAM, GO_PARAM_VALUE)
		   .makeRequest();
	
		return processForecast(resp);
	}
	
	private List<WeatherForecast> processForecast(String resp) throws HtmlChangedException {
		List<WeatherForecast> theForecast = new ArrayList<WeatherForecast>();
		// locate the table containing the forecast
		// this is done by counting the number of table elements that proceed it
		int index = resp.indexOf("<table");
		if (index == -1) {
			throw new HtmlChangedException("Weather Request finding table elements");
		}
		int cnt = 1;
		while(cnt < 7) {
			resp = resp.substring(index + 6);
			index = resp.indexOf("<table");
			if (index == -1) {
				throw new HtmlChangedException("Weather Request finding table elements");
			}
			cnt++;
		}
		resp = resp.substring(index);
		
		// now the table extract the forecast table contents
		Matcher matcher = TABLE_REG_EX.matcher(resp);
		if (!matcher.find()) {
			throw new HtmlChangedException("Weather Request Table");
		}
		resp = matcher.group(1);
		
		// extract forecast info within the table cell
		matcher = CELL_REG_EX.matcher(resp);
		if (!matcher.find()) {
			throw new HtmlChangedException("Weahter Request Table Cell");
		}
		
		// remove un-needed html elements
		String cell = matcher.group(1);
		cell = cell.replaceAll("<br>", " ");
		cell = cell.replaceAll("<b>", "");
		cell = cell.replaceAll("</b>", "");
		
		Matcher matcher2 = WEATHER_REG_EX.matcher(cell);
		if (!matcher2.find()) {
			throw new HtmlChangedException("Weather Request weather cell");
		}
		WeatherForecast forecast = new WeatherForecast();
		forecast.setTime(matcher2.group(1));
		forecast.setWeather(matcher2.group(2));
		forecast.setTemperature(matcher2.group(3));
		theForecast.add(forecast);
		
		while(matcher.find()) {
			cell = matcher.group(1);
			cell = cell.replaceAll("<br>", " ");
			cell = cell.replaceAll("<b>", "");
			cell = cell.replaceAll("</b>", "");
			
			matcher2 = WEATHER_REG_EX.matcher(cell);
			matcher2.find();
			forecast = new WeatherForecast();
			forecast.setTime(matcher2.group(1));
			forecast.setWeather(matcher2.group(2));
			forecast.setTemperature(matcher2.group(3));
			
			theForecast.add(forecast);
		}

		return theForecast;
	}
}
